const { User, Activity, UserProfile, ActivityParticipant, CheckIn } = require('../models');
const { Op } = require('sequelize');

class RecommendationService {
  // 获取用户个性化推荐
  async getUserRecommendations(userId, limit = 10) {
    try {
      const userProfile = await UserProfile.findOne({ where: { user_id: userId } });
      
      if (!userProfile) {
        // 如果用户没有画像，返回热门活动
        return await this.getPopularActivities(limit);
      }

      // 基于用户画像的内容推荐
      const contentBasedRecommendations = await this.getContentBasedRecommendations(userProfile, limit);
      
      // 基于协同过滤的推荐
      const collaborativeRecommendations = await this.getCollaborativeRecommendations(userId, limit);
      
      // 混合推荐结果
      const mixedRecommendations = this.mixRecommendations(
        contentBasedRecommendations,
        collaborativeRecommendations,
        limit
      );

      return mixedRecommendations;
    } catch (error) {
      console.error('获取推荐失败:', error);
      return await this.getPopularActivities(limit);
    }
  }

  // 基于内容的推荐
  async getContentBasedRecommendations(userProfile, limit) {
    const interests = userProfile.interests || [];
    const locationPreference = userProfile.location_preference;
    
    const whereConditions = {
      status: 'published',
      start_time: { [Op.gt]: new Date() }
    };

    // 基于兴趣标签匹配
    if (interests.length > 0) {
      whereConditions.tags = {
        [Op.overlap]: interests
      };
    }

    // 基于地理位置偏好
    if (locationPreference) {
      whereConditions.location = {
        [Op.like]: `%${locationPreference}%`
      };
    }

    const activities = await Activity.findAll({
      where: whereConditions,
      include: [
        {
          model: User,
          as: 'creator',
          attributes: ['id', 'username', 'avatar_url']
        }
      ],
      order: [['start_time', 'ASC']],
      limit
    });

    return activities.map(activity => ({
      ...activity.toJSON(),
      recommendation_score: this.calculateContentScore(activity, userProfile),
      recommendation_reason: '基于您的兴趣偏好'
    }));
  }

  // 协同过滤推荐
  async getCollaborativeRecommendations(userId, limit) {
    // 找到相似用户
    const similarUsers = await this.findSimilarUsers(userId);
    
    if (similarUsers.length === 0) {
      return [];
    }

    // 获取相似用户参与的活动
    const similarUserIds = similarUsers.map(user => user.id);
    const participatedActivities = await ActivityParticipant.findAll({
      where: {
        user_id: { [Op.in]: similarUserIds },
        status: ['registered', 'attended']
      },
      include: [
        {
          model: Activity,
          as: 'activity',
          where: {
            status: 'published',
            start_time: { [Op.gt]: new Date() }
          },
          include: [
            {
              model: User,
              as: 'creator',
              attributes: ['id', 'username', 'avatar_url']
            }
          ]
        }
      ]
    });

    // 排除用户已参与的活动
    const userParticipatedActivities = await ActivityParticipant.findAll({
      where: { user_id: userId },
      attributes: ['activity_id']
    });
    const excludeActivityIds = userParticipatedActivities.map(p => p.activity_id);

    const recommendations = participatedActivities
      .filter(p => !excludeActivityIds.includes(p.activity_id))
      .map(p => ({
        ...p.activity.toJSON(),
        recommendation_score: this.calculateCollaborativeScore(p.activity, similarUsers),
        recommendation_reason: '与您兴趣相似的用户也参与了此活动'
      }))
      .slice(0, limit);

    return recommendations;
  }

  // 找到相似用户
  async findSimilarUsers(userId, limit = 10) {
    const userProfile = await UserProfile.findOne({ where: { user_id: userId } });
    if (!userProfile) return [];

    const userInterests = userProfile.interests || [];
    if (userInterests.length === 0) return [];

    // 基于兴趣相似度找用户
    const similarProfiles = await UserProfile.findAll({
      where: {
        user_id: { [Op.ne]: userId },
        interests: { [Op.overlap]: userInterests }
      },
      include: [
        {
          model: User,
          as: 'user',
          attributes: ['id', 'username']
        }
      ],
      limit
    });

    return similarProfiles.map(profile => ({
      id: profile.user_id,
      username: profile.user.username,
      similarity_score: this.calculateUserSimilarity(userProfile, profile)
    }));
  }

  // 计算用户相似度
  calculateUserSimilarity(userProfile1, userProfile2) {
    const interests1 = userProfile1.interests || [];
    const interests2 = userProfile2.interests || [];
    
    const intersection = interests1.filter(interest => interests2.includes(interest));
    const union = [...new Set([...interests1, ...interests2])];
    
    return union.length > 0 ? intersection.length / union.length : 0;
  }

  // 计算内容推荐分数
  calculateContentScore(activity, userProfile) {
    let score = 0.5; // 基础分数
    
    const userInterests = userProfile.interests || [];
    const activityTags = activity.tags || [];
    
    // 兴趣匹配度
    const matchingTags = activityTags.filter(tag => userInterests.includes(tag));
    score += (matchingTags.length / Math.max(activityTags.length, 1)) * 0.3;
    
    // 地理位置匹配
    if (userProfile.location_preference && activity.location) {
      if (activity.location.includes(userProfile.location_preference)) {
        score += 0.2;
      }
    }
    
    return Math.min(score, 1.0);
  }

  // 计算协同过滤分数
  calculateCollaborativeScore(activity, similarUsers) {
    // 基于相似用户的参与度和相似度计算分数
    const avgSimilarity = similarUsers.reduce((sum, user) => sum + user.similarity_score, 0) / similarUsers.length;
    return Math.min(0.5 + avgSimilarity * 0.5, 1.0);
  }

  // 混合推荐结果
  mixRecommendations(contentBased, collaborative, limit) {
    const mixed = [];
    const contentWeight = 0.6;
    const collaborativeWeight = 0.4;
    
    // 合并并去重
    const allRecommendations = [...contentBased, ...collaborative];
    const uniqueActivities = new Map();
    
    allRecommendations.forEach(activity => {
      if (!uniqueActivities.has(activity.id)) {
        uniqueActivities.set(activity.id, activity);
      } else {
        // 如果活动重复，取更高的推荐分数
        const existing = uniqueActivities.get(activity.id);
        if (activity.recommendation_score > existing.recommendation_score) {
          uniqueActivities.set(activity.id, activity);
        }
      }
    });
    
    // 按推荐分数排序
    const sortedRecommendations = Array.from(uniqueActivities.values())
      .sort((a, b) => b.recommendation_score - a.recommendation_score)
      .slice(0, limit);
    
    return sortedRecommendations;
  }

  // 获取热门活动（备用推荐）
  async getPopularActivities(limit) {
    const activities = await Activity.findAll({
      where: {
        status: 'published',
        start_time: { [Op.gt]: new Date() }
      },
      include: [
        {
          model: User,
          as: 'creator',
          attributes: ['id', 'username', 'avatar_url']
        }
      ],
      order: [['current_participants', 'DESC'], ['createdAt', 'DESC']],
      limit
    });

    return activities.map(activity => ({
      ...activity.toJSON(),
      recommendation_score: 0.5,
      recommendation_reason: '热门活动推荐'
    }));
  }

  // 更新用户画像
  async updateUserProfile(userId, activityId, action) {
    try {
      const activity = await Activity.findByPk(activityId);
      if (!activity) return;

      let userProfile = await UserProfile.findOne({ where: { user_id: userId } });
      
      if (!userProfile) {
        userProfile = await UserProfile.create({
          user_id: userId,
          interests: [],
          activity_preferences: {}
        });
      }

      const interests = userProfile.interests || [];
      const activityTags = activity.tags || [];
      
      // 根据用户行为更新兴趣标签
      if (action === 'join' || action === 'checkin') {
        activityTags.forEach(tag => {
          if (!interests.includes(tag)) {
            interests.push(tag);
          }
        });
      }
      
      await userProfile.update({ interests });
    } catch (error) {
      console.error('更新用户画像失败:', error);
    }
  }
}

module.exports = new RecommendationService(); 